package arithmetic.changba;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 二叉树的序列化，和反序列化 用列表模拟
 */
public class BinTreeSerilize2 {

    // 定义一个二叉树数据结构
    class BinTreeNode {

        Integer value;
        BinTreeNode left;
        BinTreeNode right;
    }

    public static void main(String[] args) {
        new BinTreeSerilize2().init();
    }

    public void init() {
        List test = Arrays.asList(30, 10, 50, '#', '#', '#', 20, 45, '#', '#', 35, '#', '#');
        //30 10 50 # # # 20 45 # # 35 # #
        // 先用list来生成一个 二叉树
        BinTreeNode node = listToNode(test);
        System.out.println(node);
        File file = new File("a.txt");

        BinTreeNode newnode = null;
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
//			进行序列化
            serializeTree(node, new FileOutputStream(file));

            //进行反序列化
            newnode = deserializeTree(new FileInputStream(file));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        printBinTree(newnode);
    }

    /**
     * 先序遍历，把二叉树转化为io流
     */
    public void serializeTree(BinTreeNode node, OutputStream os) throws IOException {
        if (null != node) {
            os.write(node.value);
            serializeTree(node.left, os);
            serializeTree(node.right, os);
        } else {
            os.write('#');
        }
    }

    /**
     * 反序列化,给一个输入流，返回二叉树
     */
    public BinTreeNode deserializeTree(InputStream io) throws IOException {
        //一次读一个字节
        int value = io.read();
        BinTreeNode node = null;
        if (-1 != value && '#' != value) {
            node = new BinTreeNode();
            node.value = value;
            node.left = deserializeTree(io);
            node.right = deserializeTree(io);
        }
        return node;
    }

    /**
     * 打印二叉树的前序遍历数组
     */
    public void printBinTree(BinTreeNode node) {
//		再重新转化为list
        List newlist = treetoList(node, new ArrayList());
        for (Object l : newlist) {
            System.out.print(l);
            System.out.print(',');
        }
    }

    int index = 0;

    public BinTreeNode listToNode(List list) {
        Object value = list.get(index);
        index++;
        BinTreeNode node = null;
        if (value instanceof Integer) {
            node = new BinTreeNode();
            node.value = (Integer) value;
            node.left = listToNode(list);
            node.right = listToNode(list);
        }
        return node;
    }

    public List treetoList(BinTreeNode node, List list) {
        if (null != node) {
            list.add(node.value);
            treetoList(node.left, list);
            treetoList(node.right, list);
        } else {
            list.add('#');
        }
        return list;
    }

}
